package reflection;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.VarHandle;

/**
 * https://www.cnblogs.com/zhangxh20/p/7086622.html
 * JDK7 为间接调用方法引入新的 API,在 java.lang.invoke 包下，可以看作为反射的升级版，但它不像反射 API 那样显得冗长、繁重
 * MethodHandle 是抽象类，无法直接实例化，需通过 MethodHandles.Lookup 的工厂方法来创建
 */
public class T01_HelloVarHandle {

    int x = 8;
    private static VarHandle handle;

    static {
        try {
            handle = MethodHandles.lookup().findVarHandle(T01_HelloVarHandle.class, "x", int.class);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Throwable {
        T01_HelloVarHandle t = new T01_HelloVarHandle();

        // plain read / write
        System.out.println((int) handle.get(t));
        handle.set(t, 9);
        System.out.println(t.x);

        handle.compareAndSet(t, 9, 10);
        System.out.println(t.x);

        handle.getAndAdd(t, 10);
        System.out.println(t.x);

        // 获取 String 类的 replace 方法，并传参调用
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        MethodType mt = MethodType.methodType(String.class, char.class, char.class);
        MethodHandle mh = lookup.findVirtual(String.class, "replace", mt);
        String s = (String) mh.invokeExact("daddy", 'd', 'n');
    }
}